/*
 * Licensed to the Tai Ping Jin Ke
 *
 * Copyright (c) 2022 .
 * All rights reserved.
 * 项目名称：呼叫中心-数据源-数据持久层-任务调度
 * 版权说明：本软件属太平金融科技服务(上海)有限公司所有，在未获得太平金融科技服务(上海)有限公司正式授权情况下，任何企业和个人，不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。
 */
package com.taiping.cc.job.dao;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.taiping.cc.application.constant.dao.ActiveEnum;
import com.taiping.cc.application.constant.dao.BatchSizeEnum;
import com.taiping.cc.application.constant.service.PlatformServiceEnum;
import com.taiping.cc.job.dao.mapper.HttpParamConfigMapper;
import com.taiping.cc.job.dataobject.HttpParamConfigDO;
import com.taiping.cc.application.tools.StreamUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;

import com.taipingframework.mybatis.CommonDAO;
import com.taipingframework.utility.exception.DaoException;
import org.springframework.stereotype.Repository;

/**
 * <p>
 * 请求参数或响应内容解析配置表，通过该表可以拼装json报文，也可用于解析json报文 服务实现类
 * </p>
 *
 * @author 周孝兵
 * @since 2021-11-29
 */
@Repository
public class HttpParamConfigDAO extends CommonDAO<HttpParamConfigMapper, HttpParamConfigDO> {

    /**
     * 获取一个网络服务的参数配置
     */
    public List<HttpParamConfigDO> getHttpParamConfigFromPlatform(PlatformServiceEnum serviceConstant) throws DaoException {
        try {
            LambdaQueryWrapper<HttpParamConfigDO> paramWrapper = Wrappers.<HttpParamConfigDO>lambdaQuery()
                    .eq(HttpParamConfigDO::getActive, ActiveEnum.ENABLE.getCode())
                    .eq(HttpParamConfigDO::getPlatformCode, serviceConstant.getPlatformCode())
                    .eq(HttpParamConfigDO::getServiceCode, serviceConstant.getServiceCode())
                    .orderByDesc(HttpParamConfigDO::getId);
            return this.list(paramWrapper);
        } catch (Exception e) {
            throw new DaoException(e);
        }
    }

    /**
     * paramConfig 是新增还是更新，需要根据 platformCode + serviceCode + paramPosition + sourceParamPath 查询是否存在
     */
    public void saveOrUpdateList(List<HttpParamConfigDO> paramConfigList) throws DaoException {
        try {
            // 搜集数据检索条件
            List<String> platformCodeList = StreamUtils.toValueList(paramConfigList, HttpParamConfigDO::getPlatformCode);
            List<String> serviceCodeList = StreamUtils.toValueList(paramConfigList, HttpParamConfigDO::getServiceCode);
            // 批量查询
            LambdaQueryWrapper<HttpParamConfigDO> queryWrapper = Wrappers.<HttpParamConfigDO>lambdaQuery()
                    .eq(HttpParamConfigDO::getActive, ActiveEnum.ENABLE.getCode())
                    .in(HttpParamConfigDO::getPlatformCode, platformCodeList)
                    .in(HttpParamConfigDO::getServiceCode, serviceCodeList);
            List<HttpParamConfigDO> paramConfigDOList = this.list(queryWrapper);
            // 与数据库中的数据进行比对，筛选 需要 更新或添加 的 网络服务配置参数
            for (HttpParamConfigDO paramConfigInfo : paramConfigList) {
                HttpParamConfigDO httpParamConfigDO = paramConfigDOList.parallelStream()
                        .filter(filter(paramConfigInfo))
                        .findFirst()
                        .orElse(null);
                if (httpParamConfigDO == null) {
                    // 新增
                    paramConfigInfo.setParamId(IdUtil.objectId());
                    continue;
                }
                // 修改
                paramConfigInfo.setId(httpParamConfigDO.getId());
            }
            // 与数据库中的数据进行比对，筛选 需要 删除 的 网络服务配置参数
            List<HttpParamConfigDO> deleteParamConfigDOList = new ArrayList<>();
            for (HttpParamConfigDO paramConfigDO : paramConfigDOList) {
                HttpParamConfigDO paramConfigInfo = paramConfigList.parallelStream()
                        .filter(filter(paramConfigDO))
                        .findFirst()
                        .orElse(null);
                if (paramConfigInfo != null) {
                    continue;
                }
                // 删除
                paramConfigDO.setActive(ActiveEnum.DISABLE.getCode());
                deleteParamConfigDOList.add(paramConfigDO);
            }
            // 批量保存或者批量更新
            this.saveOrUpdateBatch(paramConfigList, BatchSizeEnum.INSERT_SIZE_100.getSize());
            // 批量删除已过时的配置
            this.saveOrUpdateBatch(deleteParamConfigDOList, BatchSizeEnum.INSERT_SIZE_100.getSize());
        } catch (Exception ex) {
            throw new DaoException(ex);
        }
    }

    private Predicate<HttpParamConfigDO> filter(HttpParamConfigDO configDO) throws DaoException {
        try {
            return (HttpParamConfigDO t) -> t.getPlatformCode().equalsIgnoreCase(configDO.getPlatformCode())
                    && t.getServiceCode().equalsIgnoreCase(configDO.getServiceCode())
                    && t.getParamPosition() != null
                    && t.getParamPosition().equalsIgnoreCase(configDO.getParamPosition())
                    && t.getSourceParamPath() != null
                    && t.getSourceParamPath().equalsIgnoreCase(configDO.getSourceParamPath());
        } catch (Exception e) {
            throw new DaoException(e);
        }
    }

    /**
     * 逻辑删除 网络服务参数配置
     */
    public void deleteHttpParamConfig(PlatformServiceEnum serviceConstant) throws DaoException {
        try {
            LambdaQueryWrapper<HttpParamConfigDO> queryWrapper = Wrappers.<HttpParamConfigDO>lambdaQuery()
                    .eq(HttpParamConfigDO::getActive, ActiveEnum.ENABLE.getCode())
                    .eq(HttpParamConfigDO::getPlatformCode, serviceConstant.getPlatformCode())
                    .eq(HttpParamConfigDO::getServiceCode, serviceConstant.getServiceCode());
            List<HttpParamConfigDO> httpParamConfigList = this.list(queryWrapper);
            httpParamConfigList.forEach(e -> e.setActive(ActiveEnum.DISABLE.getCode()));
            this.updateBatchById(httpParamConfigList, BatchSizeEnum.UPDATE_SIZE_50.getSize());
        } catch (Exception e) {
            throw new DaoException(e);
        }
    }
}
